package com.ljw.http.client;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liujw
 * @create 2020/10/12 16:38
 */
public class ApacheHttpClient {

    public static void main(String[] args) throws IOException {
        String urlPath = "https://10.10.20.143:28000/cfgmgr/queryPolicy";

        Map<String, String> headers = new HashMap<>(2);
        headers.put("csrfTokenHoneypot", "1c7cd1dcec5bbf358dfe25a7f99a25dfcf8ef81c3eb19a638bdd5072a7c4c6d5bbd503d27ab310b3b3125b760451efe0f8af363728aeea0dabf83b2b26337a9559adef4fd4a59c2580d934368e8b2b09d904f1cd39e506c2d9fbfba4f265e4ef27fcc73b057e2c282f541407ca40482870922448d9b29002775ee9b2217e16c2cffb266b413009c0ff15e127338b95a9aca385c687ead630ca4c264a7d1ad95985ccb83433665d97085b52c171e72e8fa2d96ebebd5fc4415a6954bbf5ec5264bd4581108e6809ed7275844ffb9ee1e7972a8fc9501bbb5fda30031a7cc9e14543febfed5a9dc59a0891f09e3c95b14aad5144281783649d057844561812de7f3b6e43be00eb58c01dc0a1166de52f71");
        headers.put("Cookie", "JSESSIONID=45248AA25270CC5A88EAC57B9C90921E");

        String paramBody = "{\"currentPage\":1,\"pageSize\":1}";

        String result = send(urlPath, headers, paramBody, "POST");
        System.out.println(result);
    }

    private static String send(String urlPath, Map<String, String> headers, String paramBody, String method) {
        String result = null;
        CloseableHttpClient httpClient = null;
        try {
            httpClient = HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(SslUtil.buildSSLContext().getSocketFactory(),null, null, (s, sslSession) -> true)).build();
            if ("POST".equalsIgnoreCase(method)) {
                result = doPost(urlPath, headers, paramBody, httpClient);
            } else if ("GET".equalsIgnoreCase(method)) {
                result = doGet(urlPath, headers, paramBody, httpClient);
            } else {
                throw new RuntimeException("Method not support :" + method);
            }

        } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            IOUtils.closeQuietly(httpClient, null);
        }
        return result;
    }

    private static String doGet(String urlPath, Map<String, String> headers, String paramBody, CloseableHttpClient httpClient) throws IOException {
        String result;// 配置信息
        RequestConfig requestConfig = RequestConfig.custom()
                // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(5000)
                // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(5000)
                // socket读写超时时间(单位毫秒)
                .setSocketTimeout(5000)
                // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(true).build();
        if (StringUtils.isNotBlank(paramBody)) {
            // TODO
        }
        HttpGet httpGet = new HttpGet(urlPath);
        httpGet.setConfig(requestConfig);
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String value = entry.getValue();
                if (StringUtils.isNotBlank(value)) {
                    httpGet.setHeader(entry.getKey(), value);
                }
            }
        }

        // 由客户端执行(发送)Get请求
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            result = resultHandler(response);
        }
        return result;
    }

    private static String doPost(String urlPath, Map<String, String> headers, String paramBody, CloseableHttpClient httpClient) throws IOException {
        String result;
        HttpPost httpPost = new HttpPost(urlPath);
        RequestConfig requestConfig = RequestConfig.custom()
                // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(5000)
                // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(5000)
                // socket读写超时时间(单位毫秒)
                .setSocketTimeout(5000)
                // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(true).build();
        httpPost.setConfig(requestConfig);

        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String value = entry.getValue();
                if (StringUtils.isNotBlank(value)) {
                    httpPost.setHeader(entry.getKey(), value);
                }
            }
        }
        if (StringUtils.isNotBlank(paramBody)) {
            StringEntity httpEntity = new StringEntity(paramBody);
            httpEntity.setContentEncoding("UTF-8");
            httpEntity.setContentType("application/json");
            httpPost.setEntity(httpEntity);
        }
        // 由客户端执行
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            result = resultHandler(response);
        }
        return result;
    }

    private static String resultHandler(CloseableHttpResponse response) throws IOException {
        String result;
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
            // 从响应模型中获取响应实体
            StringBuffer sb = new StringBuffer();
            String readLine;
            BufferedReader responseReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8));
            while ((readLine = responseReader.readLine()) != null) {
                sb.append(readLine).append(System.lineSeparator());
            }
            responseReader.close();
            result = sb.toString();
        } else {
            throw new RuntimeException("Failed ! reponseCode=" + statusLine.getStatusCode());
        }
        return result;
    }


}
